/*
- * Copyright (c) 2000-2006 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct ExpansionData {
OSOrderedSet * instances;
OSKext * kext;
+ uint32_t retain;
#if IOTRACKING
IOTrackingQueue * tracking;
#endif
reserved = IONew(ExpansionData, 1);
bzero(reserved, sizeof(ExpansionData));
#if IOTRACKING
- reserved->tracking = IOTrackingQueueAlloc(inClassName, inClassSize, 0, true);
+ uint32_t numSiteQs = 0;
+ if ((this == &OSSymbol ::gMetaClass)
+ || (this == &OSString ::gMetaClass)
+ || (this == &OSNumber ::gMetaClass)
+ || (this == &OSString ::gMetaClass)
+ || (this == &OSData ::gMetaClass)
+ || (this == &OSDictionary::gMetaClass)
+ || (this == &OSArray ::gMetaClass)
+ || (this == &OSSet ::gMetaClass)) numSiteQs = 27;
+
+ reserved->tracking = IOTrackingQueueAlloc(inClassName, (uintptr_t) this,
+ inClassSize, 0, kIOTrackingQueueTypeAlloc,
+ numSiteQs);
#endif
/* Hack alert: We are just casting inClassName and storing it in
case kNoDictionaries:
sBootstrapState = kMakingDictionaries;
// No break; fall through
+ [[clang::fallthrough]];
case kMakingDictionaries:
sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
}
sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort);
- // No break; fall through
+ // No break; fall through
+ [[clang::fallthrough]];
case kCompletedBootstrap:
{
/* Log this error here so we can include the class name.
* xxx - we should look up the other kext that defines the class
*/
+#if CONFIG_EMBEDDED
+ panic(
+#else
OSKextLog(myKext, kOSMetaClassLogSpec,
+#endif /* CONFIG_EMBEDDED */
"OSMetaClass: Kext %s class %s is a duplicate;"
"kext %s already has a class by that name.",
sStalled->kextIdentifier, (const char *)me->className,
OSMetaClassLogErrorForKext(result, myKext);
}
- OSSafeRelease(myKextName);
- OSSafeRelease(myKext);
+ OSSafeReleaseNULL(myKextName);
+ OSSafeReleaseNULL(myKext);
if (sStalled) {
OSMETA_ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) +
result = theKext->hasOSMetaClassInstances();
finish:
- OSSafeRelease(theKext);
+ OSSafeReleaseNULL(theKext);
return result;
}
OSKext::considerUnloads();
}
+/*********************************************************************
+*********************************************************************/
+bool
+OSMetaClass::removeClasses(OSCollection * metaClasses)
+{
+ OSCollectionIterator * classIterator;
+ OSMetaClass * checkClass;
+ bool result;
+
+ classIterator = OSCollectionIterator::withCollection(metaClasses);
+ if (!classIterator) return (false);
+
+ IOLockLock(sAllClassesLock);
+
+ result = false;
+ do
+ {
+ while ((checkClass = (OSMetaClass *)classIterator->getNextObject())
+ && !checkClass->getInstanceCount()
+ && !checkClass->reserved->retain) {}
+ if (checkClass) break;
+ classIterator->reset();
+ while ((checkClass = (OSMetaClass *)classIterator->getNextObject()))
+ {
+ sAllClassesDict->removeObject(checkClass->className);
+ }
+ result = true;
+ }
+ while (false);
+
+ IOLockUnlock(sAllClassesLock);
+ OSSafeReleaseNULL(classIterator);
+
+ return (result);
+}
+
+
/*********************************************************************
*********************************************************************/
const OSMetaClass *
return retMeta;
}
+/*********************************************************************
+*********************************************************************/
+const OSMetaClass *
+OSMetaClass::copyMetaClassWithName(const OSSymbol * name)
+{
+ const OSMetaClass * meta;
+
+ if (!name) return (0);
+
+ meta = 0;
+ IOLockLock(sAllClassesLock);
+ if (sAllClassesDict) {
+ meta = (OSMetaClass *) sAllClassesDict->getObject(name);
+ if (meta) OSIncrementAtomic(&meta->reserved->retain);
+ }
+ IOLockUnlock(sAllClassesLock);
+
+ return (meta);
+}
+
+/*********************************************************************
+*********************************************************************/
+void
+OSMetaClass::releaseMetaClass() const
+{
+ OSDecrementAtomic(&reserved->retain);
+}
+
/*********************************************************************
*********************************************************************/
OSObject *
OSMetaClass::allocClassWithName(const OSSymbol * name)
{
- OSObject * result = 0;
-
- const OSMetaClass * const meta = getMetaClassWithName(name);
+ const OSMetaClass * meta;
+ OSObject * result;
- if (meta) {
+ result = 0;
+ meta = copyMetaClassWithName(name);
+ if (meta)
+ {
result = meta->alloc();
+ meta->releaseMetaClass();
}
return result;
} while (0);
finish:
- OSSafeRelease(classDict);
+ OSSafeReleaseNULL(classDict);
IOLockUnlock(sAllClassesLock);
{
IOTracking * mem = (typeof(mem)) instance; mem--;
- return (IOTrackingAdd(reserved->tracking, mem, classSize, false));
+ return (IOTrackingAdd(reserved->tracking, mem, classSize, false, VM_KERN_MEMORY_NONE));
}
void OSMetaClass::trackedFree(OSObject * instance) const
return (reserved->tracking);
}
-#endif /* IOTRACKING */
\ No newline at end of file
+#endif /* IOTRACKING */